﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace Jquery.Validate.Additional
{
    /// <summary>
    /// 身份证格式验证
    /// </summary>
    public class IdCardAttribute : ValidationAttribute, IClientValidatable
    {
        public static bool IsIdCard(string idStr)
        {
            string date;
            string ai;
            const string verify = "10x98765432";
            int[] wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            string[] area = { "", "", "", "", "", "", "", "", "", "", "", "北京", "天津", "河北", "山西", "内蒙古", "", "", "", "", "", "辽宁", "吉林", "黑龙江", "", "", "", "", "", "", "", "上海", "江苏", "浙江", "安微", "福建", "江西", "山东", "", "", "", "河南", "湖北", "湖南", "广东", "广西", "海南", "", "", "", "重庆", "四川", "贵州", "云南", "西藏", "", "", "", "", "", "", "陕西", "甘肃", "青海", "宁夏", "新疆", "", "", "", "", "", "台湾", "", "", "", "", "", "", "", "", "", "香港", "澳门", "", "", "", "", "", "", "", "", "国外" };
            string[] re = Regex.Split(idStr, @"^(\d{2})\d{4}(((\d{2})(\d{2})(\d{2})(\d{3}))|((\d{4})(\d{2})(\d{2})(\d{3}[x\d])))$", RegexOptions.IgnoreCase);
            if (re.Length != 9) return false;
            int provId = int.Parse(re[1]);
            if (provId >= area.Length || area[provId] == "") return false;
            if (re[2].Length == 12)
            {
                ai = idStr.Substring(0, 17);
                date = re[4] + "-" + re[5] + "-" + re[6];
            }
            else
            {
                ai = idStr.Substring(0, 6) + "19" + idStr.Substring(6);
                date = "19" + re[4] + "-" + re[5] + "-" + re[6];
            }
            DateTime trueDate;
            if (!DateTime.TryParse(date, out trueDate))
            {
                return false;
            }
            int sum = 0;
            for (int i = 0; i <= 16; i++)
            {
                sum += int.Parse(ai.Substring(i, 1)) * wi[i];
            }
            ai += verify.Substring(sum % 11, 1);
            return (idStr.Length == 15 || idStr.Length == 18 && idStr.ToLower() == ai);
        }

        public override bool IsValid(object value)
        {
            return value == null || IsIdCard(value.ToString());
        }

        public IdCardAttribute()
        {
            ErrorMessage = "身份证号格式错误";
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = ErrorMessage,
                ValidationType = "idcard",
            };
            yield return rule;
        }
    }
}